/** This class contains the command processes/functions required by the TextBuddy class. 
 * After the user enter the command, the respective function of this class gets called for the processing of the command and 
 * update and save the file
 * 
 */

import java.io.File;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Vector;


class TextBuddyFunctions {

	//textBuddyFile is used to store the data entered by the user
	private File textBuddyFile;
	
	//textBuddyVector is a local container used for the various operations
	private Vector<String> textBuddyVector = new Vector<String>();

	/*
	 * Definition of variables for user commands and error messages used in the functions
	 */
	private static final String MESSAGE_ADD = "added to %1$s :\"%2$s\" ";
	private static final String MESSAGE_DELETE = "deleted from %1$s: \" %2$s\"";
	private static final String MESSAGE_DISPLAY = "%1$d. %2$s";
	private static final String MESSAGE_CLEAR = "all content deleted from %1$s";
	private static final String MESSAGE_SORT = "Content Sorted!";
	private static final String MESSAGE_EMPTY_FILE="File is Empty!";
	
	private static final String ERROR_OPEN_FILE="Error opening file ";
	private static final String ERROR_ADD="Exception in add function";
	private static final String ERROR_DELETE="Exception in delete function";
	private static final String ERROR_DISPLAY="Exception in display function";
	private static final String ERROR_CLEAR="Exception in clear function";
	private static final String ERROR_SEARCH="Exception in search function";
	private static final String ERROR_SORT= "Exception in sort function";
	
	//This function gets constructed based on the file name input by the user
	TextBuddyFunctions(String fileName) {

		textBuddyFile = new File(fileName);

		try {
			if (!textBuddyFile.exists()) {
				textBuddyFile.createNewFile();
			}

			else {
				readVectorFromFile();
			}
		} 
		catch (Exception e) {
			System.err.println(ERROR_OPEN_FILE + e.getMessage()); 
		}
	}
	
	//Function to read existing data from file and copy to a local vector for easy manipulation
	private void readVectorFromFile() throws Exception
	{	
		
		FileInputStream fstream = new FileInputStream(textBuddyFile);
		DataInputStream in = new DataInputStream(fstream);
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		String strLine;
		String readFromFile; 

		while ((strLine = br.readLine()) != null) { 
			textBuddyVector.add(strLine);
		}
		in.close();
	}
	
	//Function to transfer vector contents back to the file 
	private void writeVectorToFile() throws Exception {
		textBuddyFile.delete();
		textBuddyFile.createNewFile();
		String newLine="\n";
		BufferedWriter outFile = new BufferedWriter(new FileWriter(textBuddyFile));

		for (int i = 0; i < textBuddyVector.size(); i++) {
			outFile.write(textBuddyVector.elementAt(i) + newLine);   
		}

		outFile.close();
	}

	/*
	 * Function used to add user Data to the file
	 * 
	 * @param stringToAdd
	 * 					string entered by the user
	 * @return void
	 */
	public void addData(String stringToAdd) {
		try {
			textBuddyVector.add(stringToAdd);
			writeVectorToFile();
			System.out.println(String.format(MESSAGE_ADD, textBuddyFile, stringToAdd));
		} catch (Exception e) {
			System.out.println(ERROR_ADD + e.getMessage());
		}
	}

	/*
	 * Function used to delete Data at an index specified by user, from the file
	 * 
	 * @param deleteIndex
	 * 					index of the string to be deleted 
	 * @return void
	 */
	public void deleteData(int deleteIndex) {
		try {
			String strToDelete;
			strToDelete = new String(textBuddyVector.elementAt(deleteIndex - 1).toString());   
			textBuddyVector.remove(deleteIndex - 1);
			writeVectorToFile();
			System.out.println(String.format(MESSAGE_DELETE, textBuddyFile,
					strToDelete));
		} catch (Exception e) {
			System.out.println(ERROR_DELETE + e.getMessage());
		}
	}

	/*
	 * Function used to clear all Data from the file
	 *  		
	 * @return void
	 */
	public void clearData() {
		try {
			textBuddyVector.removeAllElements();
			System.out.println(String.format(MESSAGE_CLEAR, textBuddyFile));
			writeVectorToFile();
		} catch (Exception e) {
			System.out.println(ERROR_CLEAR + e.getMessage());
		}
	}

	/*
	 * Function used to display all Data, from the file
	 *  
	 * @return void
	 */
	public void displayData() {
		try {
			if(textBuddyVector.size()==0)
				System.out.println(MESSAGE_EMPTY_FILE);
			for (int i = 0; i < textBuddyVector.size(); i++) {
				System.out.println(String.format(MESSAGE_DISPLAY, (i + 1),
						textBuddyVector.elementAt(i)));
			}
		} catch (Exception e) {
			System.out.println(ERROR_DISPLAY + e.getMessage());
		}
	}
 
	/*
	 * Function used to search for a string specified by user, in the file
	 * For all strings in the search, check if it contains the specified string. If yes, 
	 * add it to result Vector and return it.
	 * 
	 * @param searchString
	 * 					index of the string to be deleted 
	 * @return Vector<String>
	 */
	public Vector<String> search(String searchString) {
		try {
			int flag = 0;
			Vector<String> searchVector=new Vector<String>(); 
			
			for (int i = 0; i < textBuddyVector.size(); i++) {
				String temp = textBuddyVector.elementAt(i).toString().toLowerCase(); 
				if (temp.contains(searchString.toLowerCase())) {
					flag = 1;
					String addString = (i+1)+". "+textBuddyVector.elementAt(i);
					searchVector.add(addString); 
				} 
			}
			
			if (flag == 0)
				System.out.println("String Not Found!");
			
			return searchVector;

		} catch (Exception e) {
			System.out.println(ERROR_SEARCH + e.getMessage());
		}
		return null;
	}

	/*
	 * Function used to sort the Data of the file, alphabetically
	 *
	 * @return Vector<String>
	 */
	public Vector<String> sortData() {
		try {
			Collections.sort(textBuddyVector);
			writeVectorToFile();
			System.out.println(String.format(MESSAGE_SORT));	
			return textBuddyVector;
		}

		catch (Exception e) {
			System.out.println(ERROR_SORT + e.getMessage());
		}
		return null;
	}

}
